Root Zanli
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
home
/
o5t6x7pgljbm
/
public_html
/
admin
/
app
/
V2
/
Services
/
Filename :
ClaimService.php
back
Copy
<?php namespace App\V2\Services; use App\Http\Controllers\Api\SPWalletController; use App\Libraries\Helpers; use App\Models\AllClaim; use App\Models\Group; use App\Models\PermissionUserEntity; use App\Models\Product; use App\Models\ProductClaimed; use App\Models\ProductClaimedApprovalFile; use App\Models\Store; use App\Models\StoreProduct; use App\Models\Task; use App\Models\TaskAssigned; use App\Models\TaskAssignedApprovalFile; use App\Models\TaskVisibility; use App\Models\User; use App\V2\Dtos\FilterClaimDTO; use App\V2\Repositories\ClaimRepository; use Carbon\Carbon; use Exception; use Illuminate\Support\Facades\Log; class ClaimService extends BaseService{ private $claimRepository; private $tuitService; private $userActivityService; public function __construct(){ $this->claimRepository = new ClaimRepository(); $this->tuitService = new TUITService(); $this->userActivityService = new UserActivityService(); } public function canClaimProduct(User $user, Group $currentGroup, Store $currentStore, Product $product, StoreProduct $storeProduct,){ //Check validity of the task $reward_expiry_date = Carbon::parse($product->expires_on)->startOfDay(); if($product->expires_on != null && now()->gte($reward_expiry_date)){ throw new Exception("Reward is already expired", 400); } //TODO: implement the product claim conditions $productSetting = $product->productSetting; $filterDto = FilterClaimDTO::builder() ->user($user)->store($currentStore)->group($currentGroup) ->productIds([$storeProduct->product_id]) ->requiredFor('CHILD') ->orderByColumn('created_at') ->order('DESC') ->build(); $claims = $this->claimRepository->filterClaims($filterDto); $product_claim = ProductClaimed::where('user_id', $user->user_id) ->where('store_product_id', $storeProduct->store_product_id)->first(); if($productSetting != null){ if(count($claims) == 0){ //TODO: check repeat claim condition // throw new Exception("Product Already claimed", 400); } else if($productSetting->repeate_after_days > 0){ $lastClaim = $claims[0]; $lastClaimDate = Carbon::parse($lastClaim->created_at)->startOfDay(); $nextClaimAllowedDate = $lastClaimDate->addDays($productSetting->repeate_after_days); $canAllowClaimToday = now()->gte($nextClaimAllowedDate); if(!$canAllowClaimToday){ throw new Exception("Product is already claimed for the duration, next allowed claim is on $nextClaimAllowedDate", 400); } } } else if(!$claims->isEmpty() && $claims[0]->status != 'REJECTED' ){ throw new Exception("Claim is already in process", 400); } else if($product_claim != null && $product_claim->status != 'REJECTED'){ throw new Exception("Reward claim is already in process", 400); } return true; } /** * check if task can be claimed or not: * 1, is task expired * 2, if already claimed without repeate_after_days check * 3, claim allowed according repeate_after_days check */ public function canClaimTask(User $user, Group $currentGroup, Store $currentStore, Task $task, TaskAssigned $taskAssigned){ //Check validity of the task $task_expiry_date = Carbon::parse($task->due_by)->startOfDay(); if($task->due_by != null && now()->gte($task_expiry_date)){ throw new Exception("Task is already expired", 400); } //check if task claim is allowed $taskSetting = $task->taskSetting; $claims = $taskAssigned->claims; if($taskSetting != null){ if($claims->isEmpty()){ //No existing claims present. } else if($claims[0]->status=='PENDING'){ return $claims[0]; } else if($taskSetting->repeate_after_days > 0){ $lastClaim = $claims[0]; $lastClaimDate = Carbon::parse($lastClaim->created_at)->startOfDay(); $nextClaimAllowedDate = $lastClaimDate->addDays($taskSetting->repeate_after_days); $canAllowClaimToday = now()->gte($nextClaimAllowedDate); if(!$canAllowClaimToday){ throw new Exception("Task is already claimed for the duration, next allowed claim is on $nextClaimAllowedDate", 400); } } } else if(!$claims->isEmpty() && !in_array($claims[0]->status,['PENDING','REJECTED']) ){ throw new Exception("Claim is already in process", 400); } else if($taskAssigned->status != 'PENDING'){ throw new Exception("Task assigned claim is already in process", 400); } return !$claims->isEmpty() ? $claims[0] : null; } public function canReviewTaskClaim(User $user, Group $currentGroup, Store $currentStore, AllClaim $claim){ $task = $claim->task; $taskAssigned = $claim->taskAssigned; //TODO: implement this "permission_user_entity" table if($task->taskSetting != null){ if($task->taskSetting->task_review_allowed_to_type == 'USER'){ $allowedPermissionOnTaskForUser = PermissionUserEntity::where('entity_type', 'TASK') ->where('entity_id', $claim->task->task_id) ->where('user_id', $user->user_id) ->where('team_id', $currentGroup->team->id) ->first(); if($allowedPermissionOnTaskForUser != null && $allowedPermissionOnTaskForUser->permission != null && $allowedPermissionOnTaskForUser->permission->name == 'TASK_REVIEW'){ Log::debug('Review allowed to UserId: '. $user->user_id .' for ClaimId:'. $claim->claim_id .', Reason: TASK_REVIEW Permission present'); return true; } } if($task->taskSetting->task_review_allowed_to_type == 'PARENTS_OR_FOSTER_AGENT'){ //returning true of the user is $roles = $user->getRoles($currentGroup->team); if($roles != null && count($roles) > 0 && (in_array('PARENT', $roles) || in_array('SOCIAL_WORKER', $roles))) { Log::debug('Review allowed to UserId: '. $user->user_id .' for ClaimId:'. $claim->claim_id .', Reason: TASK_REVIEW Role present'); return true; } } if($task->taskSetting->taskReviewAllowedBy != null){ foreach($task->taskSetting->taskReviewAllowedBy AS $taskReviewAllowedBy){ $task_review_allowed_to_type = $taskReviewAllowedBy->review_allowed_to_type; if($task_review_allowed_to_type == 'USER'){ $allowedPermissionOnTaskForUser = PermissionUserEntity::where('entity_type', 'TASK') ->where('entity_id', $claim->task->task_id) ->where('user_id', $user->user_id) ->where('team_id', $currentGroup->team->id) ->first(); if($allowedPermissionOnTaskForUser != null && $allowedPermissionOnTaskForUser->permission != null && $allowedPermissionOnTaskForUser->permission->name == 'TASK_REVIEW'){ Log::debug('Review allowed to UserId: '. $user->user_id .' for ClaimId:'. $claim->claim_id .', Reason: TASK_REVIEW Permission present'); return true; } } if($task_review_allowed_to_type == 'PARENTS_OR_FOSTER_AGENT'){ //returning true of the user is $roles = $user->getRoles($currentGroup->team); if($roles != null && count($roles) > 0 && (in_array('PARENT', $roles) || in_array('SOCIAL_WORKER', $roles))) { Log::debug('Review allowed to UserId: '. $user->user_id .' for ClaimId:'. $claim->claim_id .', Reason: TASK_REVIEW Role present'); return true; } } } } // if(in_array($task->taskSetting->visible_to, ['GLOBAL']) && $user->user_id == $currentGroup->owner_user_id){ // Log::debug('Review allowed to UserId: '. $user->user_id .' for ClaimId:'. $claim->claim_id .', Reason: Task is Globally Visible'); // return true; // } // if(in_array($task->taskSetting->visible_to, ['ZIPCODE_PARENT','ZIPCODE_PARENT_AND_CHILD']) && // $user->userAddress != null && $task->taskSetting->taskVisibility != null){ // $user_zipcode = $user->userAddress->zipcode; // $visibility_zipcode_arr = array_reduce($task->taskSetting->taskVisibility, // function(TaskVisibility $taskVisibility){ // if($taskVisibility->entity_type == 'ZIPCODE') // return $taskVisibility->entity_value; // else return null; // }); // if(in_array($user_zipcode, $visibility_zipcode_arr)){ // Log::debug('Review allowed to UserId: '. $user->user_id .' for ClaimId:'. $claim->claim_id .', Reason: Task is Visible to ZIPCODE'); // return true; // } // } // if(in_array($task->taskSetting->visible_to, ['GLOBAL_FOR_PARENT','GLOBAL_FOR_PARENT_AND_CHILD']) && // $task->taskSetting->taskVisibility != null){ // $visibility_user_id_arr = array_reduce($task->taskSetting->taskVisibility, // function(TaskVisibility $taskVisibility){ // if($taskVisibility->entity_type == 'USER') // return $taskVisibility->entity_value; // else return null; // }); // if(in_array($user->user_id, $visibility_user_id_arr)){ // Log::debug('Review allowed to UserId: '. $user->user_id .' for ClaimId:'. $claim->claim_id .', Reason: Task is Visible to PARENT'); // return true; // } // } } if($user->user_id == $currentGroup->owner_user_id && $task->group_id == $currentGroup->group_id){ Log::debug('Review allowed to UserId: '. $user->user_id .' for ClaimId:'. $claim->claim_id .', Reason: User is the owner of the group, and task belongs to the same group'); return true; } else if($user->user_id == $currentGroup->owner_user_id && $task->taskSetting != null && $task->taskSetting->visible_to == 'GLOBAL') { Log::debug('Review allowed to UserId: '. $user->user_id .' for ClaimId:'. $claim->claim_id .', Reason: User is the owner of the group, and task is global'); return true; } else if($user->user_id == $currentGroup->owner_user_id && $claim->group_id == $currentGroup->group_id){ Log::debug('Review allowed to UserId: '. $user->user_id .' for ClaimId:'. $claim->claim_id .', Reason: User is the owner of the group, and claim is also in the same group'); return true; } else { Log::debug('Review Not allowed for UserId: '. $user->user_id .' for ClaimId:'. $claim->claim_id .', Reason: User is not the owner of the group'); return false; } } public function isReviewRequiredForClaim(User $user, Task $task){ } public function getClaimsForGroup(FilterClaimDTO $filter){ $claims = $this->claimRepository->filterClaims($filter); return $claims; } public function getClaimsForUser(FilterClaimDTO $filter){ $claims = $this->claimRepository->filterClaims($filter); return $claims; } public function createNewClaimForTask(User $claimedByUser, Group $currentGroup, Store $currentStore, TaskAssigned $taskAssigned, $claim_details){ $task = $taskAssigned->task; $product = $task->product_id != null ? $task->product : null; //check if task can be claimed $previous_claim = $this->canClaimTask($claimedByUser, $currentGroup, $currentStore, $task, $taskAssigned); //create task_assigned_claim //saving taskAssigned $claim_status = 'PENDING_APPROVAL'; if($task->taskSetting != null && $task->taskSetting->review_required == false) { $taskAssigned->status = 'APPROVED'; $claim_status='APPROVED'; } else { $taskAssigned->status = 'PENDING_APPROVED'; $claim_status = 'PENDING_APPROVAL'; } $taskAssigned->task_details_for_approval = $claim_details['comments']; $result = $taskAssigned->save(); if(!$result){ throw new Exception ('failure while claiming the task', 500); } //saving claim files if($claim_details['approval_files'] != null){ foreach($claim_details['approval_files'] AS $file){ $this->saveClaimApprovalFile($taskAssigned, $file); } } $claim = null; if($previous_claim != null){ $claim = $previous_claim; $claim->status = $claim_status; $claim->updated_by_id = $claimedByUser->user_id; $claim->updated_at = now(); $claim->save(); } else { //create all_claim $claim = AllClaim::create([ 'claim_entity_type' => $task->product != null ? 'TASK_AND_PRODUCT' : 'TASK', 'task_id' => $task->task_id, 'product_id' => $task->product != null ? $task->product->product_id : null, 'task_assigned_id' => $taskAssigned->task_assigned_id, 'product_claimed_id' => null, 'store_id' => $currentStore->store_id, 'group_id' => $currentGroup->group_id, 'claimed_by_user_id' => $claimedByUser->user_id, 'status' => $claim_status, ]); $claim->save(); } if($claim_status == 'APPROVED'){ $this->awardSPToWallet($claimedByUser, $task); } $activityHistory = UserActivityService::getDetailsForTaskCompletedByChildForParent($currentGroup->owner, $claimedByUser, $currentGroup, $task, 0); $tuitTransaction = $this->tuitService->triggerTuitCreditAction($currentGroup->owner, 'COMPLETION_OF_TASKS_BY_CHILDREN_IN_GROUP', $activityHistory->activity_sub_details); $activityHistory = UserActivityService::getDetailsForTaskCompletedByChildForParent($currentGroup->owner, $claimedByUser, $currentGroup, $task, $tuitTransaction['tuit_credit']); $this->userActivityService->addActivityHistory($activityHistory->user_id, $activityHistory->group_id, $activityHistory->activity_details, $activityHistory->activity_sub_details, $activityHistory->side_effect_details); //send email and app notifications $parentUser = $currentGroup->owner; Helpers::notifyTaskCompleted($task, $parentUser, $claimedByUser); $title = "Task Claimed"; $msg = "Task '$task->task_title' is claimed by $claimedByUser->full_name"; $type = "task_claim"; $task_assigned_id = $taskAssigned->task_assigned_id; if($parentUser->device_type == 'android'){ Helpers::sendPushAndroid(array($parentUser->device_token), $title, $msg, $type, $task_assigned_id); } else if($parentUser->device_type == 'ios'){ Helpers::sendPushIOS(array($parentUser->device_token), $title, $msg, $type, $task_assigned_id); } Helpers::storeNotifications($claimedByUser->user_id, array($parentUser->user_id), $title, $msg, $type, $task_assigned_id); return $claim; } /** * claim for only product - essentially a purchase option */ public function createNewClaimForProduct(User $claimedByUser, Group $currentGroup, Store $currentStore, StoreProduct $storeProduct, $claim_details){ $product = $storeProduct->product; $this->canClaimProduct($claimedByUser, $currentGroup, $currentStore, $product, $storeProduct); //reduce sp from wallet if($product->product_sp > 0){ try{ $wallet = $this->reduceSPFromWallet($claimedByUser, $product); }catch(Exception $e){ Log::error($e->getMessage()); throw $e; } } $status = 'APPROVED'; //Saving product claim $productClaimed = ProductClaimed::create([ 'store_product_id'=>$storeProduct->store_product_id, 'user_id' => $claimedByUser->user_id, 'status' => $status, 'comments' => $claim_details['comments'], ]); $productClaimed->save(); if( ! (isset($productClaimed) && $productClaimed->product_claimed_id > 0)){ Log::info("error is saving product claim"); throw new Exception('error is saving product claim', 500,); } //create all_claim $claim = AllClaim::create([ 'claim_entity_type' => 'PRODUCT', 'task_id' => null, 'product_id' => $product->product_id , 'task_assigned_id' => null, 'product_claimed_id' => $productClaimed->product_claimed_id, 'store_id' => $currentStore->store_id, 'group_id' => $currentGroup->group_id, 'claimed_by_user_id' => $claimedByUser->user_id, 'status' => 'REDEEMED', ]); $claim->save(); //saving claim files if($claim_details['approval_files'] != null){ foreach($claim_details['approval_files'] AS $file){ $this->saveProductClaimedApprovalFile($productClaimed, $file); } } //send email and app notifications $title = 'Reward claimed'; $msg = $claimedByUser->full_name.' has claimed the '.$product->product_name.' reward.'; $type = 'product_claimed'; $parentUser = User::find($currentStore->created_by); if($parentUser->device_type == 'android'){ Helpers::sendPushAndroid(array($parentUser->device_token), $title, $msg, $type, $productClaimed->product_claimed_id); } else if($parentUser->device_type == 'ios'){ Helpers::sendPushIOS(array($parentUser->device_token), $title, $msg, $type, $productClaimed->product_claimed_id); } Helpers::storeNotifications($claimedByUser->user_id, array($parentUser->user_id), $title, $msg, $type, $productClaimed->product_claimed_id); /* Notification Code - End */ return $claim; } public function changeClaimStatus(User $user, Group $currentGroup, Store $currentStore, AllClaim $claim, $review_status, $should_notify = true){ $task_new_status = $this->getNextStatusForTask($claim, $review_status); $product_new_status = $this->getNextStatusForProduct($claim, $review_status); $claim_new_status = $this->getNextStatusForClaim($claim, $review_status); //update task_assigned_claim $taskAssigned = $claim->taskAssigned; if($taskAssigned != null){ $taskAssigned->status = $task_new_status; $taskAssigned->save(); } //update product_claim $productClaimed = $claim->productClaimed; if($productClaimed != null){ $productClaimed->status = $product_new_status; $productClaimed->save(); } //update all_claim $claim->status = $claim_new_status; $claim->reviewed_by_user_id = $user->user_id; $claim->updated_by_id = $user->user_id; $claim->updated_at = now(); $claim->save(); if($claim_new_status == 'APPROVED'){ //adding user_actiity for child $activityHistory = UserActivityService::getDetailsForTaskApprovedOrRejectedForChild($user, $taskAssigned->assigned_to_user, $currentGroup, $taskAssigned->task, $review_status, $taskAssigned->task->task_sp); $spWalletTransaction = $this->awardSPToWallet($taskAssigned->assigned_to_user, $taskAssigned->task, $activityHistory->activity_sub_details); $this->userActivityService->addActivityHistory($activityHistory->user_id, $activityHistory->group_id, $activityHistory->activity_details, $activityHistory->activity_sub_details, $activityHistory->side_effect_details); } if($should_notify && in_array($claim->claim_entity_type, ['TASK', 'TASK_AND_PRODUCT'])) { $this->sendTaskAssignedStatusChangeNotification( $user, $claim, $taskAssigned, $review_status); } if( in_array($claim->claim_entity_type, ['TASK', 'TASK_AND_PRODUCT']) && in_array($review_status, ['APPROVED','REJECTED']) ){ //adding user_activity for parent $activityHistory = UserActivityService::getDetailsForTaskApprovedOrRejectedForParent($user, $taskAssigned->assigned_to_user, $currentGroup, $taskAssigned->task, $review_status, 0); $tuitTransaction = $this->tuitService->triggerTuitCreditAction($user, 'CLAIM_REVIEW_BY_PARENT', $activityHistory->activity_sub_details); $activityHistory = UserActivityService::getDetailsForTaskApprovedOrRejectedForParent($user, $taskAssigned->assigned_to_user, $currentGroup, $taskAssigned->task, $review_status, $tuitTransaction['tuit_credit']); $this->userActivityService->addActivityHistory($activityHistory->user_id, $activityHistory->group_id, $activityHistory->activity_details, $activityHistory->activity_sub_details, $activityHistory->side_effect_details); } return $claim; } private function sendTaskAssignedStatusChangeNotification(User $user, AllClaim $claim, TaskAssigned $taskAssigned, $review_status){ //send email and app notifications if($review_status == 'APPROVED'){ $title = 'Task Approved'; $msg = $claim->task->task_title.' task has been approved.'; $childUser = User::find($taskAssigned->user_id); Helpers::notifyTaskApproved($claim->task, $user, $childUser); } if($review_status == 'REJECTED'){ $title = 'Task Rejected'; $msg = $claim->task->task_title.' task has been rejected.'; $childUser = User::find($taskAssigned->user_id); Helpers::notifyTaskRejected($claim->task, $user, $childUser); } $type = 'task_assigned'; $assignedUser = User::find($taskAssigned->user_id); if($assignedUser->device_type == 'android'){ Helpers::sendPushAndroid(array($assignedUser->device_token), $title, $msg, $type, $taskAssigned->canClaimProducttask_assigned_id); } else if($assignedUser->device_type == 'ios'){ Helpers::sendPushIOS(array($assignedUser->device_token), $title, $msg, $type, $taskAssigned->task_assigned_id); } Helpers::storeNotifications($user->user_id, array($taskAssigned->user_id), $title, $msg, $type, $taskAssigned->task_assigned_id); } private function getNextStatusForTask(AllClaim $claim, $review_status){ $new_status = null; switch($review_status){ case 'PENDING': $new_status = 'PENDING'; break; case 'PENDING_APPROVAL': $new_status = 'PENDING_APPROVED'; break; case 'APPROVED': $new_status = 'APPROVED'; break; case 'REJECTED': $new_status = 'PENDING'; break; case 'REDEEMED': $new_status = 'APPROVED'; break; default: $new_status = $review_status; break; } return $new_status; } private function getNextStatusForProduct(AllClaim $claim, $review_status){ $new_status = null; switch($review_status){ case 'PENDING': $new_status = 'PENDING_APPROVAL'; break; case 'PENDING_APPROVAL': $new_status = 'PENDING_APPROVAL'; break; case 'APPROVED': $new_status = 'APPROVED'; break; case 'REJECTED': $new_status = 'REJECTED'; break; case 'REDEEMED': $new_status = 'REWARDED'; break; default: $new_status = $review_status; break; } return $new_status; } private function getNextStatusForClaim(AllClaim $claim, $review_status){ $new_status = null; switch($review_status){ case 'PENDING': $new_status = 'PENDING'; break; case 'PENDING_APPROVAL': $new_status = 'PENDING_APPROVAL'; break; case 'APPROVED': $new_status = 'APPROVED'; break; case 'REJECTED': $new_status = $claim->claim_entity_type =='PRODUCT' ? 'REJECTED' : 'PENDING'; break; case 'REDEEMED': $new_status = 'REDEEMED'; break; default: $new_status = $review_status; break; } return $new_status; } private function reduceSPFromWallet($user, $product){ //Check if SP can be reduced if yes, reduce balance. $spWalletController = new SPWalletController(); $wallet = array(); if($spWalletController->canDebitSP($user, $product->product_sp)){ $wallet = $spWalletController->debitSP($user, $product->product_sp, [ 'transaction_title' => "Product Purchase for product_id: $product->product_id", 'ref_table' => 'product_claimed', 'ref_table_id' => null, 'description' => "Product Purchase for product_id: $product->product_id", ]); } else { throw new Exception("not enough balance to purchase the product", 400); } return $wallet; } private function awardSPToWallet($user, $task, $description = null){ $spWalletController = new SPWalletController(); $spWalletTransaction = array(); $spWalletTransaction = $spWalletController->creditSP($user, $task->task_sp, [ 'transaction_title' => "Task Claim Approved: $task->task_title", 'ref_table' => 'task_assigned', 'ref_table_id' => null, 'description' => $description == null ? "Task Claim Approved: $task->task_title" : $description, ]); return $spWalletTransaction; } private function saveClaimApprovalFile(TaskAssigned $user_task_assignment, $file){ $fileName = rand().time().'.'.$file->getClientOriginalExtension(); // Save original size image $file->move(public_path('task_claim_files'), $fileName); $task_assignment_approval_file = TaskAssignedApprovalFile::insert( ['task_assigned_id' => $user_task_assignment->task_assigned_id, 'file_name' => $fileName]); return $task_assignment_approval_file; } private function saveProductClaimedApprovalFile($productClaimed, $file){ $fileName = rand().time().'.'.$file->getClientOriginalExtension(); // Save original size image $file->move(public_path('product_claim_files'), $fileName); $productClaimedApprovalFile = ProductClaimedApprovalFile::insert( ['product_claimed_id' => $productClaimed->product_claimed_id, 'file_name' => $fileName]); return $productClaimedApprovalFile; } } ?>